using System;
using System.Collections.Generic;
using System.Text;

namespace SqlTools.CodeGenerator.Data
{
	public static class NamingHelper
	{
		public static string MemberVariableName(string className)
		{
			return "_" + ClassVariableName(className);
		}

		public static string PluralMemberVariableName(string className)
		{
			return Pluralize(MemberVariableName(className));
		}

		public static string ClassVariableName(string className)
		{
			string cvName = className;

			for ( int i = 0; i < cvName.Length; i++ )
			{
				// stop when we reach the first lower case letter
				if ( char.IsLower(cvName[i]) )
					break;

				string chr = new string(cvName[i], 1);

				cvName = ReplaceChar(cvName, chr.ToLower(), i);
			}

			cvName = TitleCase(cvName, false);

			return cvName;
		}

		public static string PluralClassVariableName(string className)
		{
			string cvName = ClassVariableName(className);
			return Pluralize(cvName);
		}

		public static string NonMemberName(string memberName)
		{
			return memberName.TrimStart(new char[] { '_' });
		}

		public static string PluralNonMemberName(string memberName)
		{
			string nmName = NonMemberName(memberName);
			return Pluralize(nmName);
		}

		public static string Pluralize(string name)
		{
			if ( String.IsNullOrEmpty(name) )
				return "";

			// check for already plural

			string ret = name;
			char lastChar = name[name.Length - 1];

			if ( lastChar == 's' || lastChar == 'S' )
			{
				ret += "es";
			}
			else
			{
				ret += "s";
			}
			return ret;
		}

		public static string TitleCase(string name)
		{
			return TitleCase(name, true);
		}

		public static string TitleCase(string name, bool capLead)
		{
			string cvName = name;

			// capitalize first char
			if ( char.IsLower(cvName[0]) && capLead )
			{
				string chr = new string(cvName[0], 1);

				cvName = ReplaceChar(cvName, chr.ToUpper(), 0);
			}

			// check for underscores and properly title case
			for ( int i = 0; i < cvName.Length; i++ )
			{
				if ( cvName[i] == '_' )
				{
					cvName = cvName.Remove(i, 1);

					if ( char.IsLower(cvName[i]) )
					{
						string chr = new string(cvName[i], 1);

						cvName = ReplaceChar(cvName, chr.ToUpper(), i);
					}
				}
			}

			return cvName;
		}

		public static string ReplaceChar(string str, string newChar, int index)
		{
			if ( index < 0 || index > str.Length - 1 )
			{
				throw new ArgumentOutOfRangeException("index", index, "index refers to a character that is outside the bounds of this string");
			}

			string cvName = str;

			string temp = "";

			if ( index > 0 )
			{
				temp = cvName.Substring(0, index);
			}

			temp += newChar + cvName.Substring(index + 1);

			return temp;

		}

		public static string RemoveID(string name)
		{
			if ( ( name.EndsWith("ID") || name.EndsWith("id") ) && ( name.ToUpper() != "ID" ) )
			{
				name = name.Substring(0, name.Length - 2);

				if ( name.EndsWith("_") )
				{
					name = name.Substring(0, name.Length - 1);
				}
			}

			return name;
		}
	}
}
